package com.mdinic.blogovi.model;

import java.io.Serializable;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.persistence.Version;
import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.roo.addon.javabean.RooJavaBean;
import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord;
import org.springframework.roo.addon.tostring.RooToString;
import org.springframework.transaction.annotation.Transactional;

@RooJavaBean
@RooToString
@Configurable
@Entity
@RooJpaActiveRecord(finders = { "findBlogsByNameEquals", "findBlogsByUrlEquals", "findBlogsByUrlLike",
        "findBlogsByNameLike", "findBlogsByAutoApproveNot", "findBlogsByBlacklistedNot" })
public class Blog implements Serializable {

    private static final long serialVersionUID = 8359396268772207762L;

    @NotNull
    private String url;

    @PersistenceContext
    transient EntityManager entityManager;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Version
    @Column(name = "version")
    private Integer version;

    @NotNull
    private Boolean autoApprove;

    @NotNull
    private Boolean blacklisted;

    public static final EntityManager entityManager() {
        EntityManager em = new Blog().entityManager;
        if (em == null)
            throw new IllegalStateException(
                    "Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)");
        return em;
    }

    public static long countBlogs() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Blog o", Long.class).getSingleResult();
    }

    public static List<com.mdinic.blogovi.model.Blog> findAllBlogs() {
        return entityManager().createQuery("SELECT o FROM Blog o", Blog.class).getResultList();
    }

    public static com.mdinic.blogovi.model.Blog findBlog(Long id) {
        if (id == null)
            return null;
        return entityManager().find(Blog.class, id);
    }

    public static List<com.mdinic.blogovi.model.Blog> findBlogEntries(int firstResult, int maxResults) {
        return entityManager().createQuery("SELECT o FROM Blog o", Blog.class).setFirstResult(firstResult)
                .setMaxResults(maxResults).getResultList();
    }

    @Transactional
    public void persist() {
        if (this.entityManager == null)
            this.entityManager = entityManager();
        this.entityManager.persist(this);
    }

    @Transactional
    public void remove() {
        if (this.entityManager == null)
            this.entityManager = entityManager();
        if (this.entityManager.contains(this)) {
            this.entityManager.remove(this);
        } else {
            Blog attached = findBlog(this.id);
            this.entityManager.remove(attached);
        }
    }

    @Transactional
    public void flush() {
        if (this.entityManager == null)
            this.entityManager = entityManager();
        this.entityManager.flush();
    }

    @Transactional
    public void clear() {
        if (this.entityManager == null)
            this.entityManager = entityManager();
        this.entityManager.clear();
    }

    @Transactional
    public com.mdinic.blogovi.model.Blog merge() {
        if (this.entityManager == null)
            this.entityManager = entityManager();
        Blog merged = this.entityManager.merge(this);
        this.entityManager.flush();
        return merged;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Boolean getAutoApprove() {
        return autoApprove;
    }

    public void setAutoApprove(Boolean autoApprove) {
        this.autoApprove = autoApprove;
    }

    public Boolean getBlacklisted() {
        return blacklisted;
    }

    public void setBlacklisted(Boolean blacklisted) {
        this.blacklisted = blacklisted;
    }

    public Long getId() {
        return this.id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Integer getVersion() {
        return this.version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public static TypedQuery<com.mdinic.blogovi.model.Blog> findBlogsByNameEquals(String name) {
        if (name == null || name.length() == 0)
            throw new IllegalArgumentException("The name argument is required");
        EntityManager em = entityManager();
        TypedQuery<Blog> q = em.createQuery("SELECT o FROM Blog AS o WHERE o.name = :name", Blog.class);
        q.setParameter("name", name);
        return q;
    }

    public static TypedQuery<com.mdinic.blogovi.model.Blog> findBlogsByNameLike(String name) {
        if (name == null || name.length() == 0)
            throw new IllegalArgumentException("The name argument is required");
        name = name.replace('*', '%');
        if (name.charAt(0) != '%') {
            name = "%" + name;
        }
        if (name.charAt(name.length() - 1) != '%') {
            name = name + "%";
        }
        EntityManager em = entityManager();
        TypedQuery<Blog> q = em
                .createQuery("SELECT o FROM Blog AS o WHERE LOWER(o.name) LIKE LOWER(:name)", Blog.class);
        q.setParameter("name", name);
        return q;
    }

    public static TypedQuery<com.mdinic.blogovi.model.Blog> findBlogsByUrlEquals(String url) {
        if (url == null || url.length() == 0)
            throw new IllegalArgumentException("The url argument is required");
        EntityManager em = entityManager();
        TypedQuery<Blog> q = em.createQuery("SELECT o FROM Blog AS o WHERE o.url = :url", Blog.class);
        q.setParameter("url", url);
        return q;
    }

    public static TypedQuery<com.mdinic.blogovi.model.Blog> findBlogsByUrlLike(String url) {
        if (url == null || url.length() == 0)
            throw new IllegalArgumentException("The url argument is required");
        url = url.replace('*', '%');
        if (url.charAt(0) != '%') {
            url = "%" + url;
        }
        if (url.charAt(url.length() - 1) != '%') {
            url = url + "%";
        }
        EntityManager em = entityManager();
        TypedQuery<Blog> q = em.createQuery("SELECT o FROM Blog AS o WHERE LOWER(o.url) LIKE LOWER(:url)", Blog.class);
        q.setParameter("url", url);
        return q;
    }

    public static TypedQuery<com.mdinic.blogovi.model.Blog> findBlogsByAutoApproveNot(Boolean autoApprove) {
        if (autoApprove == null)
            throw new IllegalArgumentException("The autoApprove argument is required");
        EntityManager em = Blog.entityManager();
        TypedQuery<Blog> q = em.createQuery("SELECT o FROM Blog AS o WHERE o.autoApprove IS NOT :autoApprove",
                Blog.class);
        q.setParameter("autoApprove", autoApprove);
        return q;
    }

    public static TypedQuery<Blog> findBlogsByBlacklistedNot(Boolean blacklisted) {
        if (blacklisted == null)
            throw new IllegalArgumentException("The blacklisted argument is required");
        EntityManager em = Blog.entityManager();
        TypedQuery<Blog> q = em.createQuery("SELECT o FROM Blog AS o WHERE o.blacklisted IS NOT :blacklisted",
                Blog.class);
        q.setParameter("blacklisted", blacklisted);
        return q;
    }

    @Override
    public String toString() {
        return "[" + id + "] " + url;
    }
}
